package org.csource.pool;

import com.freesun.web.common.utils.FileUtil;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * 测试上传
 *
 * @author yangfei
 * @created 2013-12-11
 * @desc 对fastdfs服务器集群进行性能测试验证，首次测试为添加缓存服务，二次验证增加缓存服务
 * @update 增加连接socket ProtoCommon.activeTest(trackerServer.getSocket());保存连接通常
 */
public class FastDfsImpl implements FastDfs {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    //ip
    private static String tracker_server = "192.168.0.119:22122";

    //HTTP访问服务的端口号
    private static int httpPort = 22122;
    //连接超时的时限，单位为毫秒
    private static int connectTimeout = 2000;
    //网络超时的时限，单位为毫秒
    private static int networkTimeout = 3000;
    //非法访问屏蔽
    private static Boolean Token = true;
    //字符集
    private static String Charset = "UTF-8";
    //加密
    private static String secretKey = null;


    //连接池设置
    private static int maxIdle = 50;
    private static int minIdle = 0;
    private static int maxActive = 50;
    private static long maxWait = -1L;
    private static byte whenExhaustedAction = 1;
    private static boolean testOnBorrow = false;
    private static boolean testOnReturn = false;
    private static boolean testWhileIdle = true;
    private static long timeBetweenEvictionRunsMillis = 30000L;
    private static int numTestsPerEvictionRun = -1;
    private static long minEvictableIdleTimeMillis = 60000L;

    //文件服务连接
    FastDfsObjectPool fastDfsObjectPool = null;


    public static String getCharset() {
        return Charset;
    }

    public static void setCharset(String charset) {
        Charset = charset;
    }

    public static String getTracker_server() {
        return tracker_server;
    }

    public static void setTracker_server(String tracker_server) {
        FastDfsImpl.tracker_server = tracker_server;
    }

    public static int getHttpPort() {
        return httpPort;
    }

    public static void setHttpPort(int httpPort) {
        FastDfsImpl.httpPort = httpPort;
    }

    public static int getConnectTimeout() {
        return connectTimeout;
    }

    public static void setConnectTimeout(int connectTimeout) {
        FastDfsImpl.connectTimeout = connectTimeout;
    }

    public static int getNetworkTimeout() {
        return networkTimeout;
    }

    public static void setNetworkTimeout(int networkTimeout) {
        FastDfsImpl.networkTimeout = networkTimeout;
    }

    public static Boolean getToken() {
        return Token;
    }

    public static void setToken(Boolean token) {
        Token = token;
    }

    public static String getSecretKey() {
        return secretKey;
    }

    public static void setSecretKey(String secretKey) {
        FastDfsImpl.secretKey = secretKey;
    }

    public FastDfsObjectPool getFastDfsObjectPool() {
        return fastDfsObjectPool;
    }

    public void setFastDfsObjectPool(FastDfsObjectPool fastDfsObjectPool) {
        this.fastDfsObjectPool = fastDfsObjectPool;
    }

    public static int getNumTestsPerEvictionRun() {
        return numTestsPerEvictionRun;
    }

    public static void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
        FastDfsImpl.numTestsPerEvictionRun = numTestsPerEvictionRun;
    }

    public static int getMaxIdle() {
        return maxIdle;
    }

    public static void setMaxIdle(int maxIdle) {
        FastDfsImpl.maxIdle = maxIdle;
    }

    public static int getMinIdle() {
        return minIdle;
    }

    public static void setMinIdle(int minIdle) {
        FastDfsImpl.minIdle = minIdle;
    }

    public static int getMaxActive() {
        return maxActive;
    }

    public static void setMaxActive(int maxActive) {
        FastDfsImpl.maxActive = maxActive;
    }

    public static long getMaxWait() {
        return maxWait;
    }

    public static void setMaxWait(long maxWait) {
        FastDfsImpl.maxWait = maxWait;
    }

    public static byte getWhenExhaustedAction() {
        return whenExhaustedAction;
    }

    public static void setWhenExhaustedAction(byte whenExhaustedAction) {
        FastDfsImpl.whenExhaustedAction = whenExhaustedAction;
    }

    public static boolean isTestOnBorrow() {
        return testOnBorrow;
    }

    public static void setTestOnBorrow(boolean testOnBorrow) {
        FastDfsImpl.testOnBorrow = testOnBorrow;
    }

    public static boolean isTestOnReturn() {
        return testOnReturn;
    }

    public static void setTestOnReturn(boolean testOnReturn) {
        FastDfsImpl.testOnReturn = testOnReturn;
    }

    public static boolean isTestWhileIdle() {
        return testWhileIdle;
    }

    public static void setTestWhileIdle(boolean testWhileIdle) {
        FastDfsImpl.testWhileIdle = testWhileIdle;
    }

    public static long getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }

    public static void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
        FastDfsImpl.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    public static long getMinEvictableIdleTimeMillis() {
        return minEvictableIdleTimeMillis;
    }

    public static void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
        FastDfsImpl.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }

    public void init() {

        log.debug("Tracker_server:"+this.getTracker_server());
        log.debug("G_tracker_http_port:"+this.getHttpPort());
        log.debug("G_connect_timeout:"+this.getConnectTimeout());
        log.debug("G_network_timeout:"+this.getNetworkTimeout());
        log.debug("G_anti_steal_token:"+this.getToken());
        log.debug("G_charset:"+this.getCharset());
        log.debug("G_secret_key:"+this.getSecretKey());

        //ip地址
        ClientGlobal.setG_tracker_server(this.getTracker_server());
        //HTTP访问服务的端口号
        ClientGlobal.setG_tracker_http_port(this.getHttpPort());
        //连接超时的时限，单位为毫秒
        ClientGlobal.setG_connect_timeout(this.getConnectTimeout());
        //网络超时的时限，单位为毫秒
        ClientGlobal.setG_network_timeout(this.getNetworkTimeout());
        ClientGlobal.setG_anti_steal_token(this.getToken());
        //字符集
        ClientGlobal.setG_charset(this.getCharset());
        //加密字符串
        ClientGlobal.setG_secret_key(this.getSecretKey());
    }


    /**
     * @param filePath
     * @param fileExt
     * @param fileInfo
     * @return
     * @throws java.io.IOException
     * @throws org.csource.common.MyException
     * @desc 上传文件
     */
    public int uploadFile(String filePath, String fileExt, NameValuePair[] fileInfo) throws Exception {

        int flag = 1;
        //C初始化设置
        init();

        log.debug("FilePath:"+filePath);
        log.debug("fileExt:"+fileExt);
        log.debug("fileInfo:"+fileInfo);


        TrackerServer trackerServer;
        fastDfsObjectPool =  new FastDfsObjectPool();
        trackerServer = (TrackerServer) fastDfsObjectPool.borrowObject();
        StorageServer storageServer = null;
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);

        TrackerClient trackerClient = new TrackerClient();
        trackerServer.getSocket().setKeepAlive(true);
        //网络正常后发送数据保存连接
        ProtoCommon.activeTest(trackerServer.getSocket());

        File file = new File(filePath);
        FileInputStream fis = new FileInputStream(file);
        byte[] file_buff = null;

        try {
            if (fis != null) {
                int len = fis.available();
                file_buff = new byte[len];
                fis.read(file_buff);
            }
        } finally {
            fis.close();
        }

        log.debug("file length: " + file_buff.length);

        //定义组名
        String group_name = null;
        StorageServer[] storageServers = trackerClient.getStoreStorages(trackerServer, group_name);

        if (storageServers == null) {
            log.debug("get store storage servers fail, error code: " + storageClient.getErrorCode());
        } else {
            log.debug("store storage servers count: " + storageServers.length);
            for (int k = 0; k < storageServers.length; k++) {
                log.debug(k + 1 + ". " + storageServers[k].getInetSocketAddress().getAddress().getHostAddress() + ":" + storageServers[k].getInetSocketAddress().getPort());
            }
            log.debug("");
        }

        long startTime = System.currentTimeMillis();
        //String[] results = storageClient.upload_file(file_buff, "jpg", meta_list);
        String[] results = storageClient.upload_file(file_buff, fileExt, fileInfo);
        log.debug("upload_file time used: " + (System.currentTimeMillis() - startTime) + " ms");
        if (results == null) {
            log.debug("upload file fail, error code: " + storageClient.getErrorCode());
            flag = 0;
        }

        group_name = results[0];
        String remote_filename = results[1];
        log.debug("group_name: " + group_name + ", remote_filename: " + remote_filename);
        log.debug(storageClient.get_file_info(group_name, remote_filename).toString());

        ServerInfo[] servers = trackerClient.getFetchStorages(trackerServer, group_name, remote_filename);
        if (servers == null) {
            log.debug("get storage servers fail, error code: " + trackerClient.getErrorCode());
        } else {
            log.debug("storage servers count: " + servers.length);
            for (int k = 0; k < servers.length; k++) {
                log.debug(k + 1 + ". " + servers[k].getIpAddr() + ":" + servers[k].getPort());
            }
        }
        return flag;
    }


    /**
     * @param group_name
     * @param remoteFileName
     * @throws java.io.IOException
     * @throws org.csource.common.MyException
     * @desc 文件删除
     */
    public int deleteFile(String group_name, String remoteFileName) throws IOException, MyException {

        int flag = 1;

        //ClientGlobal.init(clientPath);
        //C初始化设置
        init();
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();

        StorageServer storageServer = null;
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);
        storageClient.delete_file(group_name, remoteFileName);
        log.debug("删除成功:" + remoteFileName);
        return flag;
    }


    /**
     * @param group_name
     * @param remoteFileName
     * @throws java.io.IOException
     * @throws org.csource.common.MyException
     * @des 文件获取
     */
    public String getFile(String group_name, String remoteFileName) throws Exception {

        //ClientGlobal.init(clientPath);
        //C初始化设置
        init();
        /**
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        StorageServer storageServer = null;
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);
        FileInfo fi = storageClient.get_file_info(group_name, remoteFileName);
        String sourceIpAddr = fi.getSourceIpAddr();
         **/
        TrackerServer trackerServer;
        fastDfsObjectPool =  new FastDfsObjectPool();
        trackerServer = (TrackerServer) fastDfsObjectPool.borrowObject();
        StorageServer storageServer = null;
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);
        FileInfo fi = storageClient.get_file_info(group_name, remoteFileName);
        String sourceIpAddr = fi.getSourceIpAddr();
        long size = fi.getFileSize();
        log.debug("ip:" + sourceIpAddr + ",size:" + size);
        return "ip:" + sourceIpAddr + ",size:" + size;
    }


    /**
     * @param group_name
     * @param remoteFileName
     * @param type
     * @throws java.io.IOException
     * @throws org.csource.common.MyException
     * @desc 下载文件
     */
    public int downFile(String group_name, String remoteFileName, String localeFileName, String type) throws IOException, MyException {

        //log.debug("配置文件:" + clientPath);
        //ClientGlobal.init(clientPath);
        int flag = 1;

        //C初始化设置
        init();
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        StorageServer storageServer = null;
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);
        //获取二进制图片文件
        byte[] df = storageClient.download_file(group_name, remoteFileName);
        FileUtil.saveImage(df, localeFileName, type);

        return flag;
    }

}